`timescale 1ns / 1ps

module tb_reduce();

parameter N = 80;
parameter IN_W = 32;
parameter OUT_W = 8;

reg rst;
reg clk;
reg [IN_W-1: 0] in;
wire [OUT_W-1: 0] out;
reg  ivld, ordy;
wire irdy, ovld;

reduceWidth #(
    .N      (IN_W / OUT_W), 
    .WIDTH  (OUT_W)
)inst_reduce
(
    .clk(clk),
    .rst(rst),
    .i_vld(ivld),
    .i_rdy(irdy),
    .i_data(in),
    .o_vld(ovld),
    .o_rdy(ordy),
    .o_data(out)
);

always #5 clk = ~clk;

reg [OUT_W-1: 0] i;
integer j;
integer dice;

initial
begin
    clk = 0;
    rst = 1;
    ivld = 0;
    ordy = 0;
    #20;
    rst = 0;
    #10;
    for (i = 1; i <= N; i = i + 4)
    begin
        dice = {$random()} % 7;
        ivld = 0;
        for (j = 0; j < dice; j = j + 1) begin
            #10;
        end
        in[ 7: 0] = i;
        in[15: 8] = i + 1;
        in[23:16] = i + 2;
        in[31:24] = i + 3;
        ivld = 1;
//        ivld = {$random()} % 2;
//        $display("Test random: %b.", ivld);
        # 10;
        while (irdy == 0)
        begin
            # 10;
        end
    end
    in = 0;
    ivld = 0;
    # 100;
    $display("Done.");
    $stop;
end

initial
begin
    #20;
    while (1)
    begin
        #10;
        // ordy = 1;
        ordy = {$random()} % 2;
    end
end

endmodule
